using Vin.Extension.Cache;
using Vin.Extension.Framework.Signals.Enum;
using Vin.Extension.Framework.Signals.Options;
using Vin.Extension.Framework.Signals.ServiceInterface;
using Vin.Tool.AspNetCore.Service;
using Vin.Tool.AspNetCore.Singleton;
using Vin.Tool.Attributes;
using Vin.Tool.Core.AssertCategory;
using Vin.Tool.Core.EnumCategory;

namespace Vin.Extension.Framework.Signals.Service;

[Service(nameof(SignalType.NumberSignal))]
public class VinNumberSignalService : VinBaseService, IVinSignalService
{
    private SignalsOption Option => VinApp.GetConfig<SignalsOption>();

    private string CachePrefix(string prefix, string key) => Option.CacheKey + SignalType.NumberSignal.GetName() + ":" + (
        prefix.IsNullOrEmpty() ? "" :
        prefix.EndsWith(":") ? prefix : prefix + ":") + key;

    public async Task<string> SendSignalAsync(TimeSpan? expireTime = null, string prefix = "")
    {
        var key = Guid.NewGuid().ToString("N");
        await CacheFactory.IncrAsync(CachePrefix(prefix, key), expireTime);
        return key;
    }

    public async Task<long> CheckSignalAsync(string key, string prefix = "")
    {
        return await CacheFactory.IncrAsync(CachePrefix(prefix, key));
    }

    public async Task<SignalStatus> CheckRemoveSignalAsync(string key, string prefix = "")
    {
        var count = await CheckSignalAsync(key, prefix);
        // 未知信号
        if (count == 1)
        {
            await RemoveSignalAsync(key, prefix);
            return SignalStatus.Unknown;
        }

        // 重复信号
        if (count > 2)
        {
            return SignalStatus.Repeat;
        }

        // 已知信号
        await RemoveSignalAsync(key, prefix);
        return SignalStatus.Known;
    }

    public async Task<bool> RemoveSignalAsync(string key, string prefix = "")
    {
        return await CacheFactory.RemoveCacheAsync(CachePrefix(prefix, key));
    }
}